package com.study.talk.app.base;

import android.app.Notification;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import com.bumptech.glide.Glide;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.reflect.TypeToken;
import com.study.talk.R;
import com.study.talk.app.App;
import com.study.talk.app.chat.ChatActivity;
import com.study.talk.app.chat.GroupChatActivity;
import com.study.talk.entity.GroupInfo;
import com.study.talk.entity.GroupMessageRecord;
import com.study.talk.entity.MessageRecord;
import com.study.talk.entity.bus.UpdateHomeFragmentChatList;
import com.study.talk.entity.resp.FriendUserInfoListResponse;
import com.study.talk.entity.resp.ResultResponse;
import com.study.talk.net.NetApi;
import com.study.talk.netty.NettyClient;
import com.study.talk.netty.message.MessageType;
import com.study.talk.netty.message.TalkMessage;
import com.study.talk.netty.message.request.AcceptGroupRequest;
import com.study.talk.netty.message.request.AcceptJoinGroupRequest;
import com.study.talk.netty.message.request.AcceptRequest;
import com.study.talk.netty.message.response.AcceptGroupResponse;
import com.study.talk.netty.message.response.AcceptJoinGroupResponse;
import com.study.talk.netty.message.response.AcceptResponse;
import com.study.talk.netty.message.response.AddUserResponse;
import com.study.talk.netty.message.response.ApplyGroupResponse;
import com.study.talk.netty.message.response.GroupMessageResponse;
import com.study.talk.netty.message.response.InviteGroupResponse;
import com.study.talk.netty.message.response.MessageResponse;
import com.study.talk.util.ActivityUtil;
import com.study.talk.util.AppExecutor;
import com.study.talk.util.Constants;
import com.study.talk.util.DateUtil;
import com.study.talk.util.EventBusUtil;
import com.study.talk.net.OkHttp;
import com.study.talk.util.GsonInstance;
import com.study.talk.util.OtherMessage;
import com.study.talk.util.PopWindowUtil;
import com.study.talk.util.ToastUtil;
import com.study.talk.util.alert.AlertUtil;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

public class BaseActivity extends AppCompatActivity {

    public Boolean IS_STOP = true;

    public Handler handler = new Handler(Looper.getMainLooper());
    public ProgressDialog progressDialog;

    public Uri uri;

    public String path;

    public int friendNotificationId = 100;
    public int groupNotificationId = 10000;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(OtherMessage message) {
        if (this.getClass().getName().equals(ActivityUtil.getTopActivityName(this))) {
            switch (message.getEvent()) {
                case Constants.EVENT_NETTY_DISCONNECT: {
                    ToastUtil.showToast(this, "服务器断开连接");
                    break;
                }
                case Constants.EVENT_NETTY_RECONNECT: {
                    ToastUtil.showToast(this, "服务器重新连接成功");
                }
                case Constants.NEED_LOGIN: {
                    ToastUtil.showToast(this, "请先登录！");
                }
            }
        }
    }

    //EventBus消息分发
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(TalkMessage message) {
        if (this.getClass().getName().equals(ActivityUtil.getTopActivityName(this))) {
            switch (message.getType()) {
                case MessageType.ADD_USER_RESPONSE ->
                        handleAddUserResponse((AddUserResponse) message);
                case MessageType.ACCEPT_RESPONSE ->
                        handleAcceptAddUserResponse((AcceptResponse) message);
                case MessageType.ACCEPT_GROUP_RESPONSE ->
                        handleAcceptGroupResponse((AcceptGroupResponse) message);
                case MessageType.INVITE_GROUP_RESPONSE ->
                        handleInviteGroupResponse((InviteGroupResponse) message);
                case MessageType.APPLY_GROUP_RESPONSE ->
                        handleApplyGroupResponse((ApplyGroupResponse) message);
                case MessageType.ACCEPT_JOIN_GROUP_RESPONSE ->
                        handleAcceptJoinGroupResponse((AcceptJoinGroupResponse) message);
                case MessageType.SEND_MESSAGE_RESPONSE ->
                        handleMessageResponse((MessageResponse) message);
                case MessageType.GROUP_MESSAGE_RESPONSE ->
                        handleGroupMessageResponse((GroupMessageResponse) message);
            }
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        EventBusUtil.registerEvent(this);
        super.onCreate(savedInstanceState);
        progressDialog = new ProgressDialog(BaseActivity.this);
        progressDialog.setMessage("加载中...");
    }

    @Override
    protected void onDestroy() {
        EventBusUtil.unregisterEvent(this);
        super.onDestroy();
    }

    @Override
    protected void onResume() {
        IS_STOP = false;
        super.onResume();
    }

    @Override
    protected void onStart() {
        IS_STOP = false;
        super.onStart();
    }

    @Override
    protected void onStop() {
        IS_STOP = true;
        super.onStop();
    }


    /**
     * 消息未读保存
     */
    public void handleMessageResponse(MessageResponse messageResponse) {
        MessageRecord messageRecord = new MessageRecord(messageResponse, false, false);
        if (ActivityUtil.getTopActivityName(this).equals("com.study.talk.app.chat.ChatActivity")) {
            messageRecord.setRead(true);
            EventBusUtil.sendEvent(messageRecord);
        } else {
            //new Thread(() -> getApp().db.messageDao().insertMessage(messageRecord)).start();
            AppExecutor.getInstance().FILE_IO().execute(() -> getApp().db.messageDao().insertMessage(messageRecord));
            NetApi.getUserInfo(messageRecord.getUserId(), (user) -> {
                Intent intent = new Intent(BaseActivity.this, ChatActivity.class);
                intent.putExtra("data", GsonInstance.instance.toJson(user));
                if (getApp().isBackground) {
                    runOnUiThread(() -> {
                        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); //获取通知管理组件
                        PendingIntent pendingIntent = PendingIntent.getActivity(BaseActivity.this, 0, intent, PendingIntent.FLAG_IMMUTABLE); //设置通知意图
                        Notification notification = new NotificationCompat.Builder(BaseActivity.this, "畅聊好友消息")  //新建通知
                                .setContentTitle("来自好友" + messageRecord.getNickname() + "的消息") //通知标题
                                .setContentText(messageRecord.getMessageType() == 1 ? "\"图片\"" : messageRecord.getContent()) //通知内容
                                .setAutoCancel(true)  //点击通知后通知消失
                                .setWhen(System.currentTimeMillis())    //什么时候发送通知
                                .setSmallIcon(R.drawable.notification) //通知的图标
                                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.app_logo))
                                .setContentIntent(pendingIntent)  //放入点击通知后需要操作
                                .build();
                        //notify(int id, Notification notification)   id是通知的id，覆盖的话下次还需要使用相同的id发送通知，之前的通知就会覆盖
                        manager.notify(user.getId(), notification); //发送通知
                    });
                } else {
                    runOnUiThread(() -> {
                        EventBusUtil.sendEvent(new UpdateHomeFragmentChatList());
                        PopWindowUtil.showPopWindow(BaseActivity.this, getWindow().getDecorView(), messageRecord, () -> startActivity(intent));
                    });
                }

            }, msg -> runOnUiThread(() -> ToastUtil.showToast(BaseActivity.this, msg)));
        }

    }


    /**
     * 群聊消息未读保存
     */
    public void handleGroupMessageResponse(GroupMessageResponse messageResponse) {
        GroupMessageRecord messageRecord = new GroupMessageRecord(messageResponse, false, false);
        if (ActivityUtil.getTopActivityName(this).equals("com.study.talk.app.chat.GroupChatActivity")) {
            messageRecord.setRead(true);
            EventBusUtil.sendEvent(messageRecord);
        } else {
            /*new Thread(() -> {
                getApp().db.groupMessageDao().insertMessage(messageRecord);
            }).start();*/
            AppExecutor.getInstance().FILE_IO().execute(() -> getApp().db.groupMessageDao().insertMessage(messageRecord));
            NetApi.getGroupInfo(messageRecord.getGroupId(), (group) -> {
                Intent intent = new Intent(BaseActivity.this, GroupChatActivity.class);
                intent.putExtra("data", GsonInstance.instance.toJson(group));
                if (getApp().isBackground) {
                    runOnUiThread(() -> {
                        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                        PendingIntent pendingIntent = PendingIntent.getActivity(BaseActivity.this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
                        Notification notification = new NotificationCompat.Builder(BaseActivity.this, "畅聊群聊消息")
                                .setContentTitle("来自群" + group.getName() + "群聊成员" + messageRecord.getNickname() + "的消息")
                                .setContentText(messageRecord.getMessageType() == 1 ? "\"图片\"" : messageRecord.getContent())
                                .setAutoCancel(true)
                                .setWhen(System.currentTimeMillis())
                                .setSmallIcon(R.drawable.notification)
                                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.app_logo))
                                .setContentIntent(pendingIntent)
                                .build();
                        manager.notify(group.getId(), notification);
                    });
                } else {
                    runOnUiThread(() -> {
                        EventBusUtil.sendEvent(new UpdateHomeFragmentChatList());
                        PopWindowUtil.showPopWindow(BaseActivity.this, getWindow().getDecorView(), messageRecord, () -> startActivity(intent));
                    });
                }
            }, msg -> runOnUiThread(() -> ToastUtil.showToast(BaseActivity.this, msg)));
        }
    }


    /**
     * 好友申请处理
     */
    public void handleAddUserResponse(AddUserResponse addUserResponse) {
        AlertUtil.show(BaseActivity.this, "好友申请", "用户" + addUserResponse.getInviteName() + "申请成为你的好友", b -> {
            AcceptRequest acceptRequest = new AcceptRequest();
            acceptRequest.setRequestUserId(addUserResponse.getInviteId());
            acceptRequest.setAccept(b);
            acceptRequest.setDateTime(DateUtil.getCurrentTime());
            NettyClient.sendMessage(acceptRequest);
            if (b) {
                Handler handler = new Handler();
                handler.postDelayed(this::updateFriendList, 2000);
            }
        });
    }

    /**
     * 好友申请结果通知
     */
    public void handleAcceptAddUserResponse(AcceptResponse acceptResponse) {
        if (acceptResponse.getSuccess()) {
            AlertUtil.show(BaseActivity.this, "好友添加成功提醒", "用户" + acceptResponse.getInvitedName() + "同意了你的好友申请");
            updateFriendList();
        } else {
            AlertUtil.show(BaseActivity.this, "好友添加失败提醒", "用户" + acceptResponse.getInvitedName() + "拒绝了你的好友申请");
        }
    }


    /**
     * 加入群聊通知
     */
    public void handleAcceptGroupResponse(AcceptGroupResponse acceptGroupResponse) {
        if (acceptGroupResponse.getSuccess()) {
            AlertUtil.show(BaseActivity.this, acceptGroupResponse.getGroupName() + "群消息提醒", "用户" + acceptGroupResponse.getAcceptUserName() + "加入了群聊");
        } else {
            AlertUtil.show(BaseActivity.this, "拒绝加入群聊提醒", "用户" + acceptGroupResponse.getAcceptUserName() + "拒绝加入群聊");
        }
    }

    /**
     * 同意入群通知
     */
    public void handleAcceptJoinGroupResponse(AcceptJoinGroupResponse acceptJoinGroupResponse) {
        if (acceptJoinGroupResponse.getSuccess()) {
            AlertUtil.show(BaseActivity.this, "群消息提醒", "你已成功加入群聊" + acceptJoinGroupResponse.getGroupName());
        } else {
            AlertUtil.show(BaseActivity.this, "加入群聊" + acceptJoinGroupResponse.getGroupName() + "失败", "申请没有通过");
        }
    }

    /**
     * 邀请加入群聊处理
     */
    public void handleInviteGroupResponse(InviteGroupResponse inviteGroupResponse) {
        AlertUtil.show(BaseActivity.this, "邀请加入群聊提醒", "用户" + inviteGroupResponse.getInviteUserName() + "邀请你加入群聊" + inviteGroupResponse.getGroupName(), b -> {
            AcceptGroupRequest acceptGroupRequest = new AcceptGroupRequest();
            acceptGroupRequest.setAccept(b);
            acceptGroupRequest.setGroupId(inviteGroupResponse.getGroupId());
            acceptGroupRequest.setInviteUserId(inviteGroupResponse.getInviteUserId());
            acceptGroupRequest.setUserId(getApp().userId());
            acceptGroupRequest.setDateTime(DateUtil.getCurrentTime());
            NettyClient.sendMessage(acceptGroupRequest);
        });
    }

    /**
     * 有人申请加入群聊消息处理
     */
    public void handleApplyGroupResponse(ApplyGroupResponse applyGroupResponse) {
        AlertUtil.show(BaseActivity.this, "申请加入群聊提醒", "用户" + applyGroupResponse.getApplyUserName() + "申请加入群聊" + applyGroupResponse.getGroupName(), b -> {
            AcceptJoinGroupRequest acceptJoinGroupRequest = new AcceptJoinGroupRequest();
            acceptJoinGroupRequest.setAccept(b);
            acceptJoinGroupRequest.setGroupId(applyGroupResponse.getGroupId());
            acceptJoinGroupRequest.setUserId(applyGroupResponse.getApplyUserId());
            acceptJoinGroupRequest.setDateTime(DateUtil.getCurrentTime());
            NettyClient.sendMessage(acceptJoinGroupRequest);
        });
    }


    public App getApp() {
        return (App) getApplication();
    }

    public boolean checkInput(EditText textView, String toast) {
        if (TextUtils.isEmpty(editTrim(textView))) {
            ToastUtil.showToast(this, toast);
            return true;
        }
        return false;
    }

    public boolean checkInput(EditText textView, String toast, Integer minLength, String Toast) {
        if (TextUtils.isEmpty(editTrim(textView))) {
            ToastUtil.showToast(this, toast);
            return true;
        }
        return false;
    }

    public void setText(EditText editText, String text) {
        editText.setText(text);
    }


    //显示加载对话框
    public void showLoadingDialog() {
        progressDialog.show();
        Handler handler = new Handler();
        handler.postDelayed(() -> {
            if (progressDialog.isShowing()) progressDialog.dismiss();
        }, 5000);
    }

    //取消加载对话框
    public void dismissLoadingDialog() {
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }


    //显示底部选择图像弹窗，由用户选择拍照或选择图像
    public void showSelectPhotoDialog(ActivityResultLauncher<PickVisualMediaRequest> selectPhotoLauncher, ActivityResultLauncher<Uri> takePhotoLauncher) {
        BottomSheetDialog dialog = new BottomSheetDialog(BaseActivity.this);

        View bottomDialogView = LayoutInflater.from(BaseActivity.this).inflate(R.layout.dialog_bottom, null);
        TextView takePhoto = bottomDialogView.findViewById(R.id.take_photo);
        TextView selectPhoto = bottomDialogView.findViewById(R.id.select_photo);
        TextView cancel = bottomDialogView.findViewById(R.id.cancel);

        //点击拍照
        takePhoto.setOnClickListener(vv -> {
            takePhoto(takePhotoLauncher);
            dialog.dismiss();
        });

        //点击相册
        selectPhoto.setOnClickListener(vv -> {
            selectPhoto(selectPhotoLauncher);
            dialog.dismiss();
        });

        //点击取消 弹窗消失
        cancel.setOnClickListener(vv -> dialog.dismiss());

        dialog.setContentView(bottomDialogView);
        dialog.show();
    }

    //更新好友列表
    public void updateFriendList() {
        OkHttp.get("/friend/userInfoList/" + getApp().userId(), res -> {
            FriendUserInfoListResponse response = GsonInstance.instance.fromJson(res, FriendUserInfoListResponse.class);
            if (response.getStatus() == 200) {
                getApp().friendList = response.getData();
                runOnUiThread(() -> {
                    EventBusUtil.sendEvent(new OtherMessage(Constants.UPDATE_FRIEND_LIST));
                });
            } else {
                runOnUiThread(() -> {
                    ToastUtil.showToast(BaseActivity.this, "好友列表更新失败！");
                });
            }
        });
    }


    //更新群聊列表
    public void updateGroupList() {
        OkHttp.get("/groupInfo/get/group/list/user/id/" + getApp().userId(), res -> {
            ResultResponse<List<GroupInfo>> response = GsonInstance.instance.fromJson(res, new TypeToken<ResultResponse<List<GroupInfo>>>() {
            }.getType());
            if (response.getStatus() == 200) {
                getApp().groupList = response.getData();
                runOnUiThread(() -> EventBusUtil.sendEvent(new OtherMessage(Constants.UPDATE_GROUP_LIST)));
            } else {
                runOnUiThread(() -> ToastUtil.showToast(BaseActivity.this, "群聊列表更新失败！"));
            }
        });
    }

    //输入框去空格
    public String editTrim(EditText text) {
        return text.getText().toString().trim();
    }


    //选择图片
    public void selectPhoto(ActivityResultLauncher<PickVisualMediaRequest> selectPhotoLauncher) {
        selectPhotoLauncher.launch(new PickVisualMediaRequest.Builder()
                .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
                .build());
    }

    //拍照并换返回
    public void takePhoto(ActivityResultLauncher<Uri> takePhotoLauncher) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "IMG_" + System.currentTimeMillis() + ".jpg");
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
        uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
        takePhotoLauncher.launch(uri);
    }

    //创建通知组
    private void createNotificationGroup(String groupId, String groupName) {

        NotificationChannelGroup group = null;
        group = new NotificationChannelGroup(groupId, groupName);

        NotificationManager notificationManager = (NotificationManager) getSystemService(
                NOTIFICATION_SERVICE);

        if (notificationManager != null) {
            notificationManager.createNotificationChannelGroup(group);
        }
    }

    //加载用户头像
    public void loadUserAvatar(ImageView imageView) {
        Glide.with(BaseActivity.this).load(OkHttp.URL + getApp().userInfo.getAvatar()).into(imageView);
    }


    //手动显示键盘
    public void showKeyboard(View view) {
        InputMethodManager imm = (InputMethodManager) view.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            view.requestFocus();
            imm.showSoftInput(view, 0);
        }
    }

    //手动隐藏键盘
    public void hideKeyboard(View view) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

}
